import os.path
import time
from datetime import datetime
from typing import List
import allure
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.remote.webdriver import WebDriver
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support.wait import WebDriverWait

from utils import root_dir
from utils.log_util import logger


class BasePage:

    def __init__(self, driver: WebDriver = None):
        if not driver:
            service = Service(executable_path=r"C:\Program Files\chromedriver-win64\chromedriver.exe")
            options = Options()
            options.add_experimental_option("prefs", {
                "download_restrictions": 0,
                "download.default_directory": os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
                                                           "downloads"),
                "download.prompt_for_download": False,
                "download.directory_upgrade": True,
                "safebrowsing_for_trusted_sources_enabled": False,
                "safebrowsing.enabled": False
            })
            self.driver = webdriver.Chrome(service=service, options=options)
            self.driver.get("http://192.168.1.37:8080/")
            self.driver.implicitly_wait(5)
            self.driver.maximize_window()
        else:
            self.driver = driver

    def find(self, by, value=None) -> WebElement:
        """
        封装查找
        """
        try:
            if isinstance(by, tuple):
                logger.debug(f"使用 {by[0]} 的定位方式,进行元素 {by[1]} 的定位")
                ele = self.driver.find_element(*by)
            else:
                logger.debug(f"使用 {by} 的定位方式,进行元素 {value} 的定位")
                ele = self.driver.find_element(by, value)
            try:
                # 上色
                self.mark_element(ele)
                self.save_page_source()
            except Exception as e:
                pass
            return ele
        except Exception as e:
            self.save_screen_shot()
            self.save_page_source()
            raise e

    def mark_element(self, element: WebElement):
        """
        元素上色，加边框
        """
        self.driver.execute_script("arguments[0].style.border = '2px solid red';", element)
        self.save_screen_shot()
        time.sleep(0.2)
        self.driver.execute_script("arguments[0].style.border = '';", element)

    @staticmethod
    def get_time_name(dir_name, file_name):
        dir_path = f"{root_dir}/data/{dir_name}"
        os.makedirs(dir_path, exist_ok=True)
        return f'{dir_path}/{file_name}'

    def save_page_source(self):
        # 获取当前时间
        now = datetime.now()
        # 格式化时间，包含毫秒
        time_format = now.strftime('%m-%d-%H-%M-%S-%f')[:-3]
        html_data = self.driver.page_source
        path = self.get_time_name('page_source', f'PageSource{time_format}.html')
        with open(path, "w", encoding="utf-8") as f:
            f.write(html_data)
        allure.attach.file(path, attachment_type=allure.attachment_type.HTML)

    def save_screen_shot(self):
        # 获取当前时间
        now = datetime.now()
        # 格式化时间，包含毫秒
        time_format = now.strftime('%m-%d-%H-%M-%S-%f')[:-3]
        path = self.get_time_name('screen_shot', f'img{time_format}.png')
        self.driver.save_screenshot(path)
        allure.attach.file(path, attachment_type=allure.attachment_type.PNG)

    def finds(self, by, value=None) -> List[WebElement]:
        """
        封装查找多个
        """
        if isinstance(by, tuple):
            logger.debug(f"使用 {by[0]} 的定位方式,进行元素 {by[1]} 的定位")
            eles = self.driver.find_elements(*by)
        else:
            logger.debug(f"使用 {by} 的定位方式,进行元素 {value} 的定位")
            eles = self.driver.find_elements(by, value)
        return eles

    def find_and_click(self, by, value=None):
        """
        查找并点击
        """
        ele = self.find(by=by, value=value)
        ele.click()

    def find_and_send(self, by, value=None, text=None):
        """
        查找并输入
        """
        ele = self.find(by=by, value=value)
        logger.debug(f"进行信息{text}的输入操作")
        ele.send_keys(text)

    def wait(self, method, time_out=5):
        el = WebDriverWait(self.driver, time_out).until(method)
        return el
